<template>
  <div class="signature-pad-container">
    <canvas
      ref="canvas"
      class="signature-pad"
      v-show="!signImgUrl"
    ></canvas>
    <img
      :src="signImgUrl"
      v-if="signImgUrl"
    />
    <div class="signature-pad-buttons">
      <el-button
        type="danger"
        size="default"
        v-if="!signImgUrl"
        @click="clearSignature"
      >
        {{ $t("formgen.sign.clear") }}
      </el-button>
      <el-button
        type="primary"
        size="default"
        v-if="!signImgUrl"
        @click="saveSignature"
      >
        {{ $t("formI18n.all.confirm") }}
      </el-button>
      <el-button
        type="primary"
        size="default"
        v-if="signImgUrl"
        @click="reSignature"
      >
        {{ $t("formgen.sign.resign") }}
      </el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, defineEmits, nextTick } from "vue";
import SignaturePad from "signature_pad";
import { getUploadHeader, getUploadUrl } from "@/utils/uploadFile";
import axios from "axios";
// Define emits to notify parent component
const emit = defineEmits(["save"]);

// Refs for the canvas and the signature pad instance
const canvas = ref<HTMLCanvasElement | null>(null);
let signaturePad: SignaturePad | null = null;

// Resize the canvas to fit the container and support high DPI screens
const resizeCanvas = () => {
  if (canvas.value) {
    const ratio = Math.max(window.devicePixelRatio || 1, 1);
    canvas.value.width = canvas.value.offsetWidth * ratio;
    canvas.value.height = canvas.value.offsetHeight * ratio;
    canvas.value.getContext("2d")?.scale(ratio, ratio);
  }
};

// Mounted hook to initialize the signature pad after the component is rendered
onMounted(() => {
  initSignPad();
});

const initSignPad = () => {
  if (canvas.value) {
    signaturePad = new SignaturePad(canvas.value);
    nextTick(() => {
      resizeCanvas();
    });
    // Redraw canvas on window resize
    window.addEventListener("resize", resizeCanvas);
  }
};

// Clear the signature pad
const clearSignature = () => {
  if (signaturePad) {
    signaturePad.clear();
  }
};

const dataURLtoBlob = (dataURL: string) => {
  const arr = dataURL.split(",");
  const mime = arr[0].match(/:(.*?);/)?.[1] || "";
  const bstr = atob(arr[1]);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], { type: mime });
};

const signImgUrl = ref("");

// Save the signature as a data URL and emit it to the parent component
const saveSignature = async () => {
  if (signaturePad && !signaturePad.isEmpty()) {
    const dataURL = signaturePad.toDataURL();
    const blob = dataURLtoBlob(dataURL);
    const formData = new FormData();
    formData.append("file", blob, "signature.png"); // Append the Blob as a file

    // API request to upload the file
    const response = await axios.post(getUploadUrl(), formData, {
      headers: {
        "Content-Type": "multipart/form-data",
        ...getUploadHeader()
      }
    });
    console.log(response.data.data);
    signImgUrl.value = response.data.data;
    emit("save", response.data.data);
  } else {
    alert("Please provide a signature first.");
  }
};

const reSignature = () => {
  signImgUrl.value = "";
  clearSignature();
};
</script>

<style scoped>
.signature-pad-container {
  display: flex;
  flex-direction: column;
}

.signature-pad {
  border: var(--el-border);
  width: 100%;
  border-radius: 3px;
  height: 200px;
}

.signature-pad-buttons {
  margin-top: 10px;
}

button {
  margin: 0 5px;
  padding: 8px 12px;
  font-size: 14px;
  cursor: pointer;
}
</style>
